﻿// -----------------------------------------------------------------------
// <copyright file="BoundedMailboxQueue.cs" company="Asynkron AB">
//      Copyright (C) 2015-2025 Asynkron AB All rights reserved
// </copyright>
// -----------------------------------------------------------------------

using System.Threading;
using System.Threading.Channels;
using System.Threading.Tasks;

namespace Proto.Mailbox;

public class BoundedMailboxQueue : IMailboxQueue
{
    private readonly Channel<object> _messages;
    private volatile bool _hasMessages;
    private long _length;

    public BoundedMailboxQueue(int size, BoundedChannelFullMode fullMode = BoundedChannelFullMode.Wait)
    {
        _messages = Channel.CreateBounded<object>(new BoundedChannelOptions(size)
        {
            FullMode = fullMode
        });
    }

    public int Length => (int)Interlocked.Read(ref _length);

    public void Push(object message)
    {
        _messages.Writer.WriteAsync(message).AsTask().GetAwaiter().GetResult();

        Interlocked.Increment(ref _length);
    }

    public object? Pop()
    {
        if (_messages.Reader.TryRead(out var message))
        {
            Interlocked.Decrement(ref _length);
            _hasMessages = true;
        }
        else
        {
            _hasMessages = false;
        }

        return message;
    }

    public bool HasMessages => _hasMessages;
}